#include<pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include<unistd.h>
#include <time.h>

typedef struct condition{
    pthread_mutex_t pmutex;
    pthread_cond_t pcond;
}condition_t;

//对状态的操作函数；
//初始化
int condition_init(condition_t *cond){
    int status;
    if((status=pthread_mutex_init(&cond->pmutex,NULL)))
        return status;
    if((status=pthread_cond_init(&cond->pcond,NULL)))
        return status;  
    return 0;
}

//加锁
int condition_lock(condition_t *cond){
    return pthread_mutex_lock(&cond->pmutex);
}

//解锁
int condition_unlock(condition_t *cond){
    return pthread_mutex_unlock(&cond->pmutex);
}
//等待
int condition_wait(condition_t *cond){
    return pthread_cond_wait(&cond->pcond,&cond->pmutex);
}  
//等待固定时间
int condition_time_wait(condition_t *cond,const struct timespec *abstime){
     return pthread_cond_timedwait(&cond->pcond,&cond->pmutex,abstime);
}
//唤醒一个睡眠的线程
int condition_signal(condition_t *cond){
    return pthread_cond_signal(&cond->pcond);
}
//唤醒所有的线程
int condition_broadcast(condition_t *cond){
    return pthread_cond_broadcast(&cond->pcond);
}
//摧毁释放
int condition_destroy(condition_t *cond){
    int res;
    if((res=pthread_mutex_destroy(&cond->pmutex)))
        return res;
    if((res=pthread_cond_destroy(&cond->pcond)))
        return res;  
    return 0;
}




//线程池代码
//封装线程池中的对象需要执行的任务对象
typedef struct task{
    void *(*run)(void *args);//函数指针、需要执行的任务;
    void *arg;//参数
    struct task *next;//下一个任务
}task_t;

//线程池结构体
typedef struct thread_pool{
    condition_t ready;//状态量;
    task_t *first;//第一个任务
    task_t *last;//最后一个任务
    int count;//已有的线程数
    int idle;//空闲线程数
    int max_threads;//最大线程
    int quit;//是否quit
}thread_pool_t;

void *thread_routine(void *arg){
    struct timespec abstime;
    int timeout;
    printf("thread %d is starting\n",(int)pthread_self());
    thread_pool_t *pool=(thread_pool_t*)arg;
    while(1){
        timeout=0;
        condition_lock(&pool->ready);
        //最开始为空闲
        pool->idle++;
        while(pool->first==NULL&&!pool->quit){
            printf("thread %d is waiting\n",(int)pthread_self());
            clock_gettime(CLOCK_REALTIME,&abstime);
            abstime.tv_sec+=2;
            int status=condition_time_wait(&pool->ready,&abstime);
            if(status==ETIMEDOUT){
                printf("thread %d  wait timed out\n",(int)pthread_self());
                timeout=1;
                break;
            }
        }
        pool->idle--;
        if(pool->first!=NULL){
            //取出线程执行;
            task_t *t=pool->first;
            pool->first=pool->first->next;
            //执行任务需要时间,解锁
            condition_unlock(&pool->ready);
            t->run(t->arg);
            //执行完,释放
            free(t);
            //加锁
            condition_lock(&pool->ready);
        }
        //退出线程池
        if(pool->quit&&pool->first==NULL){
            pool->count--;//当前工作线程-1
            //没有线程了，通知主线程，全部任务已经完成;
            if(pool->count==0){
                condition_signal(&pool->ready);
            }
            condition_unlock(&pool->ready);
            break;
        }
        //超时,跳出销毁线程
        if(timeout==1){
            pool->count--;//当前工作线程-1
            condition_unlock(&pool->ready);
            break;
        }
        condition_unlock(&pool->ready);
    }
    printf("thread %d  is exiting\n",(int)pthread_self());
    return NULL;
}

void thread_init(thread_pool_t *pool,int threads){
    condition_init(&pool->ready);
    pool->first=NULL;
    pool->last=NULL;
    pool->count=0;
    pool->idle=0;
    pool->max_threads=threads;
    pool->quit=0;
}

void thread_add(thread_pool_t *pool,void *(*run)(void *arg),void *arg){
    task_t *new_task=(task_t *)malloc(sizeof(task_t));
    new_task->run=run;
    new_task->arg=arg;
    new_task->next=NULL;
    condition_lock(&pool->ready);
    if(pool->first==NULL){//第一个
        pool->first=new_task;
    }else{
        pool->last->next=new_task;
    }
    pool->last=new_task;

    //线程池有空闲,唤醒
    if(pool->idle>0){
        condition_signal(&pool->ready);
    }
    //当线程池中线程个数没有达到设定最大值,创建一个新线程
    else if(pool->count<pool->max_threads){
        pthread_t tid;
        pthread_create(&tid,NULL,thread_routine,pool);
        pool->count++;
    }
    condition_unlock(&pool->ready);
}

void thread_destory(thread_pool_t *pool){
    if(pool->quit){
        return ;
    }
    condition_lock(&pool->ready);
    //设置销毁的标记为1
    pool->quit=1;
    //线程池中线程个数大于0
    if(pool->count>0){
        //对于等待的线程，发送信号唤醒
        if(pool->idle>0){
            condition_broadcast(&pool->ready);
        }
        //正在执行任务的线程，等代结束任务
        while(pool->count){
            condition_wait(&pool->ready);
        }
    }
    condition_unlock(&pool->ready);
    condition_destroy(&pool->ready);
}


void* mytask(void *arg){
    printf("thread %d working on task %d\n",(int)pthread_self(),*(int *)arg);
    sleep(1);
    free(arg);
    return NULL;
}

int main(){
    thread_pool_t pool;
    //初始化 线程池,最多三个线程
    thread_init(&pool,3);
    for(int i=0;i<10;i++){
        int *arg=(int *)malloc(sizeof(int));
        *arg=i;
        thread_add(&pool,mytask,arg);
    }
    thread_destory(&pool);
    return 0;
}